home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.4d7 source / NCSA⁄BYU TCP⁄IP / bkgr.c < prev    next >
Text File  |  1991-08-09  |  33KB  |  1,466 lines

  1. /*
  2. *  Background procedures for rcp and ftp
  3. *             11/86          Tim Krauskopf
  4. *  National Center for Supercomputing Applications
  5. *
  6. ****************************************************************************
  7. *                                                                          *
  8. *      part of:                                                            *
  9. *      Network utilities for NCSA Telnet                                   *
  10. *      by Tim Krauskopf                                                    *
  11. *                                                                          *
  12. *      National Center for Supercomputing Applications                     *
  13. *      152 Computing Applications Building                                 *
  14. *      605 E. Springfield Ave.                                             *
  15. *      Champaign, IL  61820                                                *
  16. *                                                                          *
  17. *    Copyright (c) 1987, Board of Trustees of the University of Illinois   *
  18. *                                                                          *
  19. ****************************************************************************
  20. *
  21. */
  22. #include <stdio.h>
  23. #include <fcntl.h>
  24. #include <string.h>
  25.  
  26. #include <Memory.h>
  27. #include <CType.h>
  28. #include <Dialogs.h>
  29. #include <ToolUtils.h>    /* BYU - for GetIndString() */
  30.  
  31. #include "whatami.h"
  32. #include "hostform.h"
  33. #include "menu.h"
  34. #include "user.h"
  35. #include "tools.h"
  36. #include "util.h"
  37. #include "macutil.h"
  38. #include "macbinary.h"
  39. #include "binsubs.h"
  40. #include "configrec.h"
  41. #include "maclook.h"
  42.  
  43. #define HTELNET 23
  44. #define HRSHD 514
  45. #define HFTP 21
  46. #define BUFFERS 8000
  47. #define PATHLEN 256
  48. #define MSG_RESOURCE_ID 23227    /* BYU */
  49.  
  50. #ifdef PC
  51.  
  52. #define RCPSEGSIZE 1024
  53. #define EOLCHAR 10
  54.  
  55. #ifdef MSC
  56. #define O_RAW O_BINARY
  57. #endif
  58.  
  59. #else
  60.  
  61. #define MACBINARY
  62.  
  63. #ifdef MACBINARY
  64. int
  65.     MacBinary=0;
  66. MBFile
  67.     *MBopen(),
  68.     *mbfp=NULL;
  69. extern int
  70.     defaultv;                        /* Default Volume from Maclook/Menu */
  71. #endif
  72.  
  73. #define RCPSEGSIZE 512
  74. #define O_RAW O_RDONLY
  75. #define EOLCHAR 13
  76. #endif
  77.  
  78.  
  79. int32 atol(),lseek();
  80.  
  81. extern void ftpmess();
  82. char *firstname(),*nextname(),*nextfile;
  83.  
  84. static  int
  85.     ftpenable=0,                /* is file transfer enabled? */
  86.     rcpenable=0,                /* is rcp enabled? */
  87.     ftpdata=-1,                    /* port for ftp data connection */
  88.     fnum=-1,                    /* port number for incoming ftp */
  89.     rsnum=-1,                    /* port number for incoming rshell */
  90.     rserr=-1;                    /* port number for rshd() stderr */
  91.  
  92. #ifdef PC
  93. static unsigned char xs[BUFFERS+10],    /* buffer space for file transfer */
  94.         pathname[PATHLEN],            /* space to keep path names */
  95.         newfile[PATHLEN],            /* current file being received */
  96.         myuser[17],                    /* user name on my machine */
  97.         hisuser[17],                /* user name on his machine */
  98.         waitchar;                    /* character waiting for from net */
  99. #else
  100. static  unsigned char *xs=0L,    /* buffer space for file transfer */
  101.         *pathname=0L,            /* space to keep path names */
  102.         *newfile=0L,            /* current file being received */
  103.         myuser[17],                    /* user name on my machine */
  104.         hisuser[17],                /* user name on his machine */
  105.         waitchar;                    /* character waiting for from net */
  106. #endif PC
  107.  
  108. static int 
  109.     curstate = -1,            /* state machine for background processes */
  110.     retstate = 200,            /* to emulate a subroutine call */
  111.     ftpstate = 0,            /* state of the ftp data transfer */
  112.     isdir=0,                /* flag for rcp target pathname */
  113.     waitpos=0,                /* marker for gathering strings from net */
  114.     cnt=0,                    /* number of characters from last netread() */
  115.     fh=0,                    /* file handle when transfer file is open */
  116.     ftpfh=0,                /* file handle for ftp data */
  117.     rc=0,                    /* telnet flag */
  118.     xp=0,                    /* general pointer */
  119.     towrite=0,                /* file transfer pointer */
  120.     len=0;                    /* file transfer length */
  121.  
  122. static long int
  123.     filelen=0L;                /* length of current file for transfer */
  124.  
  125. extern char * mungbuf;
  126. static char crfound=0;
  127.  
  128.  
  129. extern char Sptypes[NPORTS];            /* flags for port #'s */
  130.  
  131. #define PFTP 1
  132. #define PRCP 2
  133. #define PDATA 3
  134.  
  135. #ifdef PC
  136.  
  137. #define ga()  while (!netwrite(rsnum,"",1)) netsleep(0)
  138.  
  139. /************************************************************************/
  140. /*  unsetrshd
  141. *   remove the acceptance of rshd calls (rcp)
  142. */
  143. unsetrshd()
  144.     {
  145.     netclose(rsnum);
  146.     rsnum = -1;
  147.     rcpenable = 0;
  148. }
  149.  
  150. /************************************************************************/
  151.  
  152. setrshd()
  153. {
  154.     int i;
  155. /*
  156. *  set up to receive a rsh call connection 
  157. */
  158.     if (rsnum >= 0)
  159.         return(0);
  160.     curstate = 199;                    /* waiting for connection */
  161.     i = netsegsize(RCPSEGSIZE);
  162.     rsnum = netlisten(HRSHD);
  163.     netsegsize(i);
  164.     if (rsnum >= 0)
  165.         Sptypes[rsnum] = PRCP;
  166.  
  167.     rcpenable = 1;
  168. }
  169.  
  170.  
  171. /************************************************************************/
  172. /*  rshell
  173. *   take an incoming rshell request and service it.  Designed to handle
  174. *   rcp primarily.
  175. */
  176. rshd(code)
  177.     int code;
  178.     {
  179.     int i,j;
  180.  
  181.     if (!rcpenable)
  182.         return(0);
  183.  
  184.     switch (curstate) {
  185.         case 199:                    /* wait to get started */
  186.             if (code != CONOPEN)
  187.                 break;
  188.  
  189.             curstate = 0;
  190.             netputuev(SCLASS,RCPACT,rsnum);        /* keep us alive */
  191.  
  192.             break;
  193.             
  194. /*
  195. * in effect, this is a subroutine that captures network traffic while
  196. * waiting for a specific character to be received
  197. */
  198.         case 50:
  199.             while (0 < (cnt = netread(rsnum,&xs[waitpos],1))) {
  200.                 if (xs[waitpos] == waitchar) {
  201.                     curstate = retstate;
  202.                     netputuev(SCLASS,RCPACT,rsnum);        /* keep us alive */
  203.                     break;
  204.                 }
  205.                 else 
  206.                     waitpos += cnt;
  207.             }
  208.             netpush(rsnum);
  209.             break;
  210.  
  211.         case 51:                /* for recursion, passes straight through */
  212.             break;
  213.  
  214.         case 0:                    /* waiting for first string */
  215.             retstate = 1;
  216.             curstate = 50;
  217.             waitchar = 0;
  218.             waitpos = 0;
  219.             netputuev(SCLASS,RCPACT,rsnum);        /* keep us alive */
  220.             break;
  221.  
  222.         case 1:                    /* we have received stderr port number */
  223.             i = atoi(xs);        /* port number */
  224.             curstate = 51;
  225. #ifdef notneeded
  226. /*
  227. *  caution, netrespond calls netsleep()
  228. *  which will call this routine
  229. *  careful with the synchronicity!
  230. */
  231.             if (i)        /* zero means, don't bother */
  232.                 rserr = netrespond(i,rsnum,1);    /* respond to rsh */
  233.             else
  234. #else
  235.             if (i) {
  236.                 cnt = -1;        /* abort it all, we don't take rsh */
  237.                 break;
  238.             }
  239.             else
  240. #endif
  241.                 rserr = -1;
  242.  
  243.             retstate = 2; curstate = 50;
  244.             waitpos = 0; waitchar = 0;
  245.             break;
  246.  
  247.         case 2:                /* get user name, my machine */
  248.             strncpy(myuser,xs,16);
  249.  
  250.             retstate = 3; curstate = 50;
  251.             waitpos = 0; waitchar = 0;
  252.             break;
  253.  
  254.         case 3:             /* get user name, his machine */
  255.             strncpy(hisuser,xs,16);
  256. /*            ftransinfo(hisuser); */
  257.  
  258.             retstate = 4; curstate = 50;
  259.             waitchar = 0; waitpos = 0;
  260.  
  261.             break;
  262.  
  263.         case 4:
  264. /*            ftransinfo(xs);*/
  265. /*
  266. * ACK receipt of command line
  267. */
  268.             if (rserr >= 0)
  269.                 netwrite(rserr,&xp,1);        /* send null byte */
  270.             else {
  271.                 ga();            /* send NULL on main connection */
  272.             }
  273.  
  274.             if (!strncmp(xs,"rcp ",4)) {
  275. /*
  276. *  rcp will be using wildcards, target must be a directory
  277. */
  278.                 if (!strncmp(&xs[4],"-d -t",5)) {
  279.                     strncpy(pathname,&xs[10],PATHLEN);
  280.                     if (direxist(pathname)) {
  281. /*                        ftransinfo("no directory by that name ");*/
  282.                         netwrite(rsnum,"\001 No dir found ",16);
  283.                         netpush(rsnum);
  284.                         cnt = -1;
  285.                         break;
  286.                     }
  287.  
  288.                     isdir = 1;
  289.                     retstate = 20; curstate = 50;
  290.                     waitchar = '\012'; waitpos = 0;
  291.  
  292.                     ga();        /* ready for them to start */
  293.                     break;
  294.                 }
  295. /*
  296. * target could be a directory or a complete file spec
  297. */
  298.                 if (!strncmp(&xs[4],"-t",2)) {
  299.                     strncpy(pathname,&xs[7],PATHLEN);
  300.                     if (!direxist(pathname)) 
  301.                         isdir = 1;
  302.                     else
  303.                         isdir = 0;
  304.  
  305.                     retstate = 20 ; curstate = 50;
  306.                     waitchar = '\012'; waitpos = 0;
  307.  
  308.                     ga();            /* ready for rcp to start */
  309.                     break;
  310.                 }
  311. /*
  312. *  rcp is requesting me to transfer file(s) (or giving directory name)
  313. */
  314.                 if (!strncmp(&xs[4],"-f",2)) {
  315.                     strncpy(pathname,&xs[7],PATHLEN);
  316.  
  317. /*
  318. *  direxist returns whether the path spec refers to a directory, and if
  319. *  it does, prepares it as a prefix.  Therefore, if it is a dir, we append
  320. *  a '*' to it to wildcard all members of the directory.
  321. *  Firstname() takes a file spec (with wildcards) and returns a pointer
  322. *  to a prepared ACTUAL file name.  nextname() returns successive ACTUAL
  323. *  filenames based on firstname().
  324. */
  325.                     if (!direxist(pathname)) {
  326.                         i = strlen(pathname);
  327.                         pathname[i] = '*';        /* all members of directory*/
  328.                         pathname[++i] = '\0';
  329.                     }
  330.                     nextfile = firstname(pathname);
  331.  
  332.                     if (nextfile == NULL) {
  333. /*                        ftransinfo(" file or directory not found ");*/
  334.                         netwrite(rsnum,"\001 File not found ",18);
  335.                         netpush(rsnum);
  336.                         cnt = -1;
  337.                     }
  338.                     else {
  339.                         /* wait for other side to be ready */
  340.                         retstate = 30;    curstate = 50;
  341.                         waitchar = 0; waitpos = 0;
  342.                     }
  343.                     break;
  344.                 }
  345.             }
  346.  
  347.             break;
  348.  
  349.         case 20:
  350.             xs[waitpos] = '\0';        /* add terminator */
  351.  
  352. /*
  353. *  get working values from command line just received
  354. *  open file for receive
  355. */
  356.             if (xs[0] != 'C' || xs[5] != ' ') {
  357. /*                ftransinfo(" Cannot parse filename line "); */
  358.                 netwrite(rsnum,"\001 Problem with file name ",26);
  359.                 cnt = -1;
  360.                 break;
  361.             }
  362.  
  363.             filelen = atol(&xs[6]);
  364.  
  365.             for (i = 6; xs[i] != ' '; i++) 
  366.                 if (!xs[i]) {
  367. /*                    ftransinfo(" premature EOL ");*/
  368.                     netwrite(rsnum,"\001 Problem with file name ",26);
  369.                     cnt = -1;
  370.                     break;
  371.                 }
  372.  
  373.             strcpy(newfile,pathname);        /* path spec for file */
  374.  
  375.             if (isdir)                        /* add file name for wildcards */
  376.                 strcat(newfile,&xs[++i]);
  377.  
  378.             if (0 > (fh = creat(newfile,O_RAW))) {
  379.                 netwrite(rsnum,"\001 Cannot open file for write ",29);
  380.                 cnt = -1;
  381.                 break;
  382.             }
  383.             netputevent(USERCLASS,RCPBEGIN,-1);
  384.             ga();                            /* start sending the file to me */
  385.             xp = len = 0;
  386.             curstate = 21;                    /* receive file, fall through */
  387.             break;
  388.  
  389.         case 21:
  390.             do {
  391.             /* wait until xs is full before writing to disk */
  392.                 if (len <= 0) {
  393.                     if (xp) {
  394.                         write(fh,xs,xp);
  395.                         xp = 0;
  396.                     }
  397.                     if (filelen > (long)BUFFERS)
  398.                         len = BUFFERS;
  399.                     else
  400.                         len = (int)filelen;
  401.                 }
  402.  
  403.                 cnt = netread(rsnum,&xs[xp],len);
  404.  
  405.                 filelen -= (long)cnt;
  406.                 len -= cnt;
  407.                 xp += cnt;
  408.  
  409. /*                printf(" %ld %d %d %d ",filelen,len,xp,cnt);
  410.                 n_row(); n_puts(""); */
  411.  
  412.                 if (filelen <= 0L || cnt < 0) {
  413.                     write(fh,xs,xp);        /* write last block */
  414.                     close(fh);
  415.                     fh = 0;
  416.                     
  417.                     /* wait for NULL byte at end after closing file */
  418.                     curstate = 50;  retstate = 22;
  419.                     waitchar = 0;   waitpos = 0;
  420.                     break;
  421.                 }
  422.  
  423.             } while (cnt > 0);
  424.             break;
  425.  
  426.         case 22:
  427.             /* cause next sequence of bytes to be saved as next filename
  428.                 to transfer     */
  429.             ga();            /* tell other side, I am ready */
  430.             waitchar = '\012'; waitpos = 0;
  431.             curstate = 50; retstate = 20;
  432.             break;
  433.  
  434. /*
  435. *  transfer file(s) to the sun via rcp
  436. */
  437.         case 30:
  438.             if (0 > (fh = open(nextfile,O_RAW))) {
  439.                 netwrite(rsnum,"\001 File not found ",19);
  440. /*                ftransinfo("Cannot open file to transfer: ");
  441.                 ftransinfo(nextfile); */
  442.                 cnt = -1;
  443.                 break;
  444.             }
  445.             netputevent(USERCLASS,RCPBEGIN,-1);
  446.             filelen = lseek(fh,0L,(short)2);    /* how long is file? */
  447.             lseek(fh,0L,0);                /* back to beginning */
  448.  
  449.             for (i=0,j=-1; nextfile[i] ; i++)
  450.                 if (nextfile[i] == '\\')
  451.                     j = i;
  452.  
  453.             sprintf(xs,"C0755 %lu %s\012",filelen,&nextfile[j+1]);
  454.             netwrite(rsnum,xs,strlen(xs));    /* send info to other side */
  455.  
  456. /*            ftransinfo(xs);                     check it */
  457.  
  458.             retstate = 31; curstate = 50;
  459.             waitchar = 0;  waitpos = 0;
  460.  
  461.             towrite = xp = 0;
  462.             break;
  463.  
  464.         case 31:
  465. /*
  466. *   we are in the process of sending the file 
  467. */
  468.             netputuev(SCLASS,RCPACT,rsnum);        /* keep us alive */
  469.  
  470.             if (towrite <= xp) {
  471.                 towrite = read(fh,xs,BUFFERS);
  472.                 xp = 0;
  473.                 filelen -= (long)towrite;
  474.             }
  475.             i = netwrite(rsnum,&xs[xp],towrite-xp);
  476.             if (i > 0)
  477.                 xp += i;
  478.  
  479. /*            printf(" %d %d %d %ld\012",i,xp,towrite,filelen);
  480.             n_row();
  481. */
  482. /*
  483. *  done if:  the file is all read from disk and all sent
  484. *  or other side has ruined connection
  485. */
  486.             if ((filelen <= 0L && xp >= towrite) || netest(rsnum)) {
  487.                 close(fh);
  488.                 fh = 0;
  489.                 nextfile = nextname();        /* case of wildcards */
  490.                 ga(); 
  491.                 netputuev(SCLASS,RCPACT,rsnum);
  492.                 if (nextfile == NULL)
  493.                     retstate = 32;
  494.                 else
  495.                     retstate = 30;
  496.                 curstate = 50;
  497.                 waitchar = 0;    waitpos = 0;
  498.             }
  499.             break;
  500.         case 32:
  501.             cnt = -1;
  502.             break;
  503.         case 5:
  504.             break;
  505.         default:
  506.             break;
  507.  
  508.     }
  509.  
  510. /*
  511. *  after reading from connection, if the connection is closed,
  512. *  reset up shop.
  513. */
  514.     if (cnt < 0) {
  515.         if (fh > 0) {
  516.             close(fh);
  517.             fh = 0;
  518.         }
  519.         curstate = 5;
  520.         cnt = 0;
  521.         netclose(rsnum);
  522.         rsnum = -1;
  523.         netputevent(USERCLASS,RCPEND,-1);
  524.  
  525.         setrshd();                    /* reset for next transfer */
  526.     }
  527.  
  528.  
  529. }
  530.  
  531. #endif
  532.  
  533. /***********************************************************************/
  534. /***********************************************************************/
  535. /***********************************************************************/
  536. /************************************************************************/
  537. /*  ftp section
  538. *   This should be extracted from rcp so that it compiles cleanly
  539. */
  540.  
  541. #if 0    /* BYU - replaced by CRESP code below */
  542. #define CRESP(A)  netpush(fnum);netwrite(fnum, messs[(A)], strlen(messs[(A)]))
  543. #endif    /* BYU */
  544.  
  545. #define FASCII 0
  546. #define FIMAGE O_RAW
  547. #define FAMODE 0
  548. #define FIMODE 1
  549. #define FMMODE 2            /* Mac Binary, when ready */
  550.  
  551. static int rfstate,
  552.     portnum[8],
  553.     ftpfilemode=FASCII,            /* how to open ze file */
  554.     ftptmode=FAMODE;            /* how to transfer ze file on net */
  555.  
  556. static uint16 fdport;
  557.  
  558. unsigned char messs[100];        /* BYU */
  559.  
  560. void CRESP(msg_number) int msg_number; {            /* BYU */
  561.   GetIndString(messs,MSG_RESOURCE_ID,msg_number+1);    /* BYU */
  562.   netpush(fnum);                                    /* BYU */
  563.   netwrite(fnum, &messs[1], (size_t) messs[0]);        /* BYU */
  564. }                                                    /* BYU */
  565.  
  566. void setftp
  567.   (
  568.     void
  569.   )
  570.     {
  571. /*
  572. *  set up to receive a telnet connection for ftp commands
  573. */
  574.     rfstate = 0;
  575.     ftpstate = 0;
  576.     fnum = netlisten(HFTP);
  577.     ftpenable = 1;
  578.  
  579.     if (fnum >= 0)                /* signal that events should be caught */
  580.         Sptypes[fnum] = PFTP;
  581.  
  582.     strcpy(myuser,"unknown");    /* set unknown user name */
  583. }
  584.  
  585. void unsetftp
  586.   (
  587.     void
  588.   )
  589.     {
  590.     rfstate = 0;
  591.     ftpstate = 0;
  592.     netclose(fnum);
  593.     fnum = -1;
  594.     ftpenable = 0;
  595. }
  596.  
  597. #if 0        /* BYU - Converted to STR# resource number 23227 */
  598. /***********************************************************************/
  599. /*
  600. *  resident ftp server -- enables initiation of ftp without a username
  601. *  and password, as long as this telnet is active at the same time
  602. *  Now checks for the need of passwords.
  603. */
  604.  
  605. static char *messs[] = {
  606. #ifdef PC
  607.                         "220 PC Resident FTP server, ready \015\012",
  608. #else
  609.                         "220 Macintosh Resident FTP server, ready \015\012",
  610. #endif
  611.                         "451 Error in processing list command \015\012",
  612.                         "221 Goodbye \015\012",                        /*2*/
  613.                         "200 This space intentionally left blank <   > \015\012",
  614.                         "150 Opening connection \015\012",
  615.                         "226 Transfer complete \015\012",            /*5*/
  616.                         "200 Type set to A, ASCII transfer mode \015\012",
  617.                         "200 Type set to I, binary transfer mode \015\012",
  618.                         "500 Command not understood \015\012",        /*8*/
  619.                         "200 Okay \015\012",
  620.                         "230 User logged in \015\012",
  621.                         "550 File not found \015\012",                /*11*/
  622.                         "501 Directory not present or syntax error\015\012",
  623.                         "250 Chdir okay\015\012",
  624.                         "257 \"",
  625.                         "\" is the current directory \015\012",        /*15*/
  626.                         "501 File not found \015\012",
  627.                         "504 Parameter not accepted, not implemented\015\012",
  628.                         "200 Stru F, file structure\015\012",
  629.                         "200 Mode S, stream mode\015\012",        /*19*/
  630.                         "202 Allocate and Account not required for this server\015\012",
  631.                         "501 Cannot open file to write, check for valid name\015\012",
  632.                         "530 USER and PASS required to activate me\015\012",
  633.                         "331 Password required\015\012",      /*23 */
  634.                         "530 Login failed\015\012",
  635.                         "200 MacBinary Mode enabled\015\012",
  636.                         "200 MacBinary Mode disabled\015\012",  /*26 */
  637.                         "552 Disk write error, probably disk full\015\012",
  638.                         "214-NCSA Telnet FTP server, supported commands:\015\012",
  639.                         "    USER  PORT  RETR  ALLO  PASS  STOR  CWD  XCWD  XPWD  LIST  NLST\015\012",
  640. #ifdef MAC
  641.                         "    HELP  QUIT  MODE  TYPE  STRU  ACCT  NOOP  MACB\015\012",  /*30*/
  642.                         "    MACB is MacBinary and must be done with TYPE I\015\012",
  643. #else
  644.                         "    HELP  QUIT  MODE  TYPE  STRU  ACCT  NOOP\015\012",
  645.                         "    A Macintosh version of NCSA Telnet is also available.\015\012",
  646. #endif
  647.                         "214 Direct comments and bugs to telbug@ncsa.uiuc.edu\015\012",
  648.                         "200 Type set to I, binary transfer mode [MACBINARY ENABLED]\015\012",                /* 33 */
  649.                         "200 Type set to I, binary transfer mode [macbinary disabled]\015\012",
  650.                 ""};
  651.  
  652. /***********************************************************************/
  653. #endif        /* BYU */
  654.  
  655. /* ftpgo
  656. *  open the FTP data connection to the remote host
  657. */
  658. void ftpgo
  659.   (
  660.     void
  661.   )
  662.     {
  663.     int savest;
  664.     struct machinfo *m;
  665.  
  666.     xs[0] = portnum[0];
  667.     xs[1] = portnum[1];
  668.     xs[2] = portnum[2];
  669.     xs[3] = portnum[3];
  670.  
  671.     netfromport(20);     /* ftp data port */
  672.  
  673.     if (NULL == (m = Slookip(xs))) {        /* use default entry */
  674.         if (NULL == (m = Shostlook("default")))
  675.             return;
  676.         savest = m->mstat;
  677.         m->mstat = HAVEIP;
  678.         movebytes(m->hostip,xs,4);
  679.         ftpdata = Snetopen(m,fdport);
  680.         m->mstat = savest;
  681.         movebytes(m->hostip,"\0\0\0\0",4);
  682.         return;
  683.     }
  684.  
  685.     ftpdata = Snetopen(m,fdport);
  686.  
  687. }
  688.  
  689. void rftpd
  690.   (
  691.     int code
  692.   )
  693.     {
  694.     int i;
  695.     char tempp[256];
  696.     char theDir[256];
  697.     if (!ftpenable)
  698.         return;
  699.  
  700.     netpush(fnum);
  701.  
  702.     switch (rfstate) {
  703.         case 0:
  704.             if (code != CONOPEN) 
  705.                 break;
  706.             ftpfilemode = FASCII;
  707.             ftptmode = FAMODE;
  708.             netputevent(USERCLASS,FTPCOPEN,-1);
  709. #ifndef PC
  710.             if (!xs) xs=(char *)NewPtr(BUFFERS+10);
  711.             if (!pathname) pathname=(char *)NewPtr(PATHLEN);
  712.             if (!newfile) newfile=(char *)NewPtr(PATHLEN);
  713. #endif PC
  714.             rfstate = 1;                /* drop through */
  715.         case 1:
  716.             CRESP(0);
  717.             netgetftp(portnum,fnum);    /* get default ftp information */
  718.             for (i=0; i<4; i++)            /* copy IP number */
  719.                 hisuser[i] = portnum[i];
  720.             fdport = portnum[6]*256+portnum[7];
  721.  
  722.             waitpos = 0; waitchar = '\012';
  723.             rfstate = 50;               /* note skips over */
  724.             if (Sneedpass()) 
  725.                 retstate = 3;                /* check pass */
  726.             else
  727.                 retstate = 5;                /* who needs one ? */
  728.             break;
  729.         case 3:                /* check for passwords */
  730.         case 4:
  731.             waitpos = 0;  waitchar = '\012';
  732.             rfstate = 50;  
  733.             if (!strncmp("USER",xs,4)) {
  734.                 if (strlen(xs) < 6)                /* make sure blank name stays blank */
  735.                     xs[5] = myuser[0] = 0;
  736.                 strncpy(myuser,&xs[5],16);        /* keep user name */
  737.                 netputevent(USERCLASS,FTPUSER,-1);
  738.                 CRESP(23);
  739.                 retstate = 4;        /* wait for password */
  740.                 break;
  741.             }
  742.             if (!strncmp("PASS",xs,4)) {
  743.                 if (Scheckpass(myuser,&xs[5])) {
  744.                     netputevent(USERCLASS,FTPPWOK,-1);
  745.                     CRESP(10);
  746.                     retstate = 5;
  747.                 }
  748.                 else {
  749.                     netputevent(USERCLASS,FTPPWNO,-1);
  750.                     CRESP(24);
  751.                     retstate = 3;
  752.                 }
  753.                 break;
  754.             }
  755.             if (!strncmp("QUIT",xs,4)) {
  756.                 CRESP(2);
  757.                 cnt = -1;
  758.             }
  759.             else {
  760.                 CRESP(22);
  761.             }
  762.             retstate = 3;            /* must have password first */
  763.             break;                
  764.                 
  765. /*
  766. *  interpret commands that are received from the other side
  767. */
  768.             
  769.         case 5:
  770. #ifdef PC
  771.             for (i=4; i< strlen(xs); i++)
  772.                 if (xs[i] == '/')        /* flip slashes */
  773.                     xs[i] = '\\';
  774. #endif
  775.  
  776. /*
  777. *  set to a safe state to handle recursion
  778. *  wait for another command line from client
  779. *  
  780. */
  781.             rfstate = 50; retstate = 5;
  782.             waitchar = '\012';  waitpos = 0;
  783.  
  784.             if (!strncmp(xs,"LIST",4) || !strncmp(xs,"NLST",4)) {
  785.                 if ((strlen(xs) < 6) || xs[5] == '.')
  786.                     strcpy(xs,"LIST *");
  787.  
  788.                 nextfile = firstname(&xs[5]);    /* find first name */
  789.                 if (nextfile == NULL) {
  790.                     CRESP(16);
  791.                 }
  792.                 else {
  793.                     ftpgo();            /* open the connection */
  794.                     fdport = portnum[6]*256+portnum[7]; /* reset to def */
  795.                     if (ftpdata >= 0)
  796.                         Sptypes[ftpdata] = PDATA;
  797.                     ftpstate = 40;        /* ready to transmit */
  798.                     CRESP(4);
  799.                     netputevent(USERCLASS,FTPLIST,-1);
  800.                 }
  801.             }
  802.             else if (!strncmp(xs,"CWD",3)) {
  803.                 if (chgdir(&xs[4])) {            /* failed */
  804.                     CRESP(12);
  805.                 }
  806.                 else {                        /* success */
  807.                     CRESP(13);
  808.                 }
  809.             }
  810.             else if (!strncmp(xs,"STOR",4))
  811.               {
  812. #ifdef MACBINARY
  813.               /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */
  814.                 int
  815.                     MBflag;
  816.                 if ((!MacBinary) || (ftptmode == FAMODE))
  817.                     MBflag = MB_DISABLE;
  818.                 else
  819.                     MBflag = 0;
  820.                 mbfp = MBopen
  821.                   (
  822.                     &xs[5],
  823.                     defaultv,
  824.                     MB_WRITE | MBflag
  825.                   );
  826.                 if (mbfp == 0L)
  827.                   {
  828.                     CRESP(21);
  829.                     break;
  830.                   }
  831.                 else
  832.                     ftpfh = 12;
  833. #else
  834.  
  835.                 if (0 > (ftpfh = creat(&xs[5],ftpfilemode))) {
  836.                     CRESP(21);
  837.                     break;
  838.                 }
  839. #endif
  840.  
  841.                 ftpstate = 0;
  842.  
  843.                 strncpy(newfile,&xs[5],PATHLEN-1);
  844.                 
  845.  
  846.                 ftpgo();                /* open connection */
  847.                 fdport = portnum[6]*256+portnum[7]; /* reset to def */
  848.                 if (ftpdata >= 0)
  849.                     Sptypes[ftpdata] = PDATA;
  850.  
  851.                 CRESP(4);
  852.  
  853.                 ftpstate = 30;        /* ready for data */
  854.               }
  855.  
  856.             else if (!strncmp(xs,"RETR",4))
  857.               {
  858. #ifdef MACBINARY
  859.               /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */
  860.                 int
  861.                     MBflag;
  862.                 if ((!MacBinary) || (ftptmode == FAMODE))
  863.                     MBflag = MB_DISABLE;
  864.                 else
  865.                     MBflag = 0;
  866.                 mbfp = MBopen
  867.                   (
  868.                     &xs[5],
  869.                     defaultv,
  870.                     MB_READ | MBflag
  871.                   );
  872.                 if (mbfp == 0L) {
  873.                     CRESP(11);
  874.                     break;
  875.                 }
  876.                 ftpfh = 12;
  877. #else
  878.                 if (0 > (ftpfh = open(&xs[5],ftpfilemode))) {
  879.                     CRESP(11);
  880.                     break;
  881.                 }
  882. #endif
  883.                 strncpy(newfile,&xs[5],PATHLEN-1);
  884.  
  885.                 dopwd(theDir,256);                    /* get directory */
  886.                 sprintf(tempp,"remote <-- %s/%s\015\012",theDir,newfile);
  887.                 ftpmess(tempp);
  888.  
  889.                 ftpgo();                /* open connection */
  890.                 fdport = portnum[6]*256+portnum[7]; /* reset to def */
  891.  
  892.                 ftpstate = 20;        /* ready for data */
  893.                 if (ftpdata >= 0)
  894.                     Sptypes[ftpdata] = PDATA;
  895.  
  896.                 CRESP(4);
  897.               }
  898.             else if (!strncmp(xs,"TYPE",4)) {
  899.                 if (toupper(xs[5]) == 'I') {
  900.                     ftpfilemode = FIMAGE;
  901.                     ftptmode = FIMODE;
  902. #ifdef MACBINARY
  903.                 if (MacBinary) {
  904.                     CRESP( 33);                        /* Binary on, MACB ON */
  905.                 }
  906.                 else {
  907.                     CRESP( 34);                        /* Binary on, MACB off */
  908. #else
  909.                     CRESP(7);
  910. #endif MACBINARY
  911.                 }
  912.                 }
  913.                 else if (toupper(xs[5]) == 'A') {
  914.                     ftpfilemode = FASCII;
  915.                     ftptmode = FAMODE;
  916.                     CRESP(6);
  917.                 }
  918.                 else {
  919.                     CRESP(17);
  920.                 }
  921.  
  922.             }
  923. #ifdef MACBINARY
  924.             else if (!strncmp(xs,"MACB",4)) {
  925.                 if (toupper(xs[5]) == 'E') {
  926.                     MacBinary = 1;
  927.                     CRESP(25);
  928.                 }
  929.                 else {
  930.                     MacBinary = 0;
  931.                     CRESP(26);
  932.                 }
  933.                 DisplayMacBinary();            /* post an event ? */
  934.             }
  935. #endif
  936.             else if (!strncmp(xs,"PORT",4)) {
  937. /*
  938. * get the requested port number from the command given
  939. */
  940.                 sscanf(&xs[5],"%d,%d,%d,%d,%d,%d",&portnum[0],&portnum[1],
  941.                 &portnum[2],&portnum[3],&portnum[4],&portnum[5]);
  942.                 fdport = portnum[4]*256+portnum[5];
  943.                 CRESP(3);
  944.             }
  945.             else if (!strncmp(xs,"QUIT",4)) {
  946.                 CRESP(2);
  947.                 rfstate = 60;
  948.                 netputuev(CONCLASS,CONDATA,fnum);    /* post back to me */
  949.             }
  950.             else if (!strncmp(xs,"XPWD",4) || !strncmp(xs,"PWD",3)) {
  951.                 CRESP(14);                        /* start reply */
  952.                 dopwd(xs,1000);                    /* get directory */
  953.                 netwrite(fnum,xs,strlen(xs));    /* write dir name */
  954.                 CRESP(15);                        /* finish reply */
  955.             }
  956.             else if (!strncmp(xs,"USER",4)) {
  957.                 if (strlen(xs) < 6)                /* make sure blank name stays blank */
  958.                     xs[5] = myuser[0] = 0;
  959.                 strncpy(myuser,&xs[5],16);        /* keep user name */
  960.                 netputevent(USERCLASS,FTPUSER,-1);
  961.                 /* confirm log in without password */
  962.                 CRESP(10);
  963.             }
  964.             else if (!strncmp(xs,"STRU",4)) {    /* only one stru allowed */
  965.                 if (xs[5] == 'F') {
  966.                     CRESP(18); }
  967.                 else {
  968.                     CRESP(17); }
  969.             }
  970.             else if (!strncmp(xs,"MODE",4)) {    /* only one mode allowed */
  971.                 if (xs[5] == 'S') {
  972.                     CRESP(19); }
  973.                 else {
  974.                     CRESP(17); }
  975.             }
  976.             else if (!strncmp(xs,"ALLO",4) || !strncmp(xs,"ACCT",4)) {
  977.                 CRESP(20); }
  978.             else if (!strncmp(xs,"HELP",4)) {
  979.                 for (i=28; i<33; i++) {
  980.                     CRESP(i); }
  981.             }
  982.             else if (!strncmp(xs,"NOOP",4)) {
  983.                 CRESP(9); }
  984.             else {            /* command not understood */
  985.                 CRESP(8); 
  986.             }
  987.  
  988.             break;
  989.  
  990. /*
  991. *  subroutine to wait for a particular character
  992. */
  993.         case 50:
  994.             while (0 < (cnt = netread(fnum,&xs[waitpos],1))) {
  995.                 if (xs[waitpos] == waitchar) {
  996.                     rfstate = retstate;
  997.  
  998.                     while (xs[waitpos] < 33)        /* find end of string */
  999.                         waitpos--;
  1000.                     xs[++waitpos] = '\0';            /* put in terminator */
  1001.  
  1002.                     for (i=0; i<4; i++)                /* want upper case */
  1003.                         xs[i] = toupper(xs[i]);
  1004.  
  1005.                     break;
  1006.                 }
  1007.                 else
  1008.                     waitpos += cnt;
  1009.  
  1010.             }
  1011.             break;
  1012.  
  1013.         case 60:                    /* wait for message to get through */
  1014.                                     /* or connection is broken */
  1015. /*            printf("                  %d,%d",netpush(fnum),netest(fnum));*/
  1016.             if (!netpush(fnum) || netest(fnum))
  1017.                 cnt = -1;
  1018.             else
  1019.                 netputuev(CONCLASS,CONDATA,fnum);    /* post back to me */
  1020.             break;
  1021.  
  1022.         default:
  1023.             break;
  1024.  
  1025.     }
  1026.  
  1027.     if (cnt < 0) {
  1028. #ifdef MACBINARY
  1029.         if (mbfp) {
  1030.             MBclose( mbfp );
  1031.             mbfp = NULL;
  1032.         }
  1033. #else
  1034.         if (ftpfh > 0) {
  1035.             ftpfh = 0;
  1036.             close(ftpfh);
  1037.         }
  1038. #endif
  1039.         if (ftpdata > 0) {
  1040.             netclose(ftpdata);
  1041.             netputevent(USERCLASS,FTPEND,-1);
  1042.         }
  1043.         rfstate = 100;
  1044.         ftpstate = 0;
  1045.         cnt = 0;
  1046.         netclose(fnum);
  1047.         netputevent(USERCLASS,FTPCLOSE,-1);
  1048.         fnum = -1;
  1049.         ftpdata = -1;
  1050.         setftp();                /* reset it */
  1051.     }
  1052.  
  1053. }
  1054.  
  1055. /*
  1056. *  important note:  for Sfread, nwant must be 256 bytes LARGER than the amount
  1057. *  which will probably be read from the connection.
  1058. *  Sfread will stop anywhere from 0 to 256 bytes short of filling nwant
  1059. *  number of bytes.
  1060. */
  1061. int Sfread
  1062.   (
  1063.     int pnum,
  1064.     void *buf,
  1065.     int nwant
  1066.   )
  1067.     {
  1068.     int i,ndone,lim;
  1069.     char *p,*q;
  1070.  
  1071.     if (nwant < 1024)
  1072.         return(-1);
  1073.  
  1074.     ndone = 0;
  1075.  
  1076.     while (ndone < nwant - 1024) {
  1077.  
  1078.         if (0 >= (lim = netread(pnum,mungbuf,1024))) {
  1079.             if (ndone || !lim)            /* if this read is valid, but no data */
  1080.                 return(ndone);
  1081.             else
  1082.                 return(-1);                /* if connection is closed for good */
  1083.         }
  1084.  
  1085.         p = mungbuf;
  1086.         q = (char *) buf + ndone;
  1087.  
  1088. /*        printf("\012 lim=%d done=%d want=%d",lim,ndone,nwant);
  1089.         n_row();
  1090. */
  1091.         for (i=0; i < lim; i++) {
  1092.  
  1093.             if (crfound) {
  1094.                 if (*p == 10)
  1095.                     *q++ = EOLCHAR;
  1096.                 else if (*p == 0)
  1097.                     *q++ = 13;            /* CR-NUL means CR */
  1098.                 crfound = 0;
  1099.             }
  1100.             else if (*p == 13)
  1101.                 crfound = 1;
  1102.             else 
  1103.                 *q++ = *p;                /* copy the char */
  1104.  
  1105.             p++;
  1106.         }
  1107.  
  1108.         ndone = q-buf;                    /* count chars ready */
  1109.     }
  1110.  
  1111.     return(ndone);
  1112. }
  1113.  
  1114. /***************************************************************************/
  1115. /*  Sfwrite
  1116. *   Write an EOL translated buffer into netwrite.
  1117. *   Returns the number of bytes which were processed from the incoming
  1118. *   buffer.  Uses its own 1024 byte buffer for the translation (with Sfread).
  1119. */
  1120.  
  1121. int Sfwrite
  1122.   (
  1123.     int pnum,
  1124.     void *buf,
  1125.     int nsrc
  1126.   )
  1127.     {
  1128.     int i,ndone,nout,lim;
  1129.     char *p,*q;
  1130.  
  1131.     ndone = 0;
  1132.  
  1133.     while (ndone < nsrc) {
  1134.  
  1135.         if (0 > ( i = netroom(pnum)))
  1136.             return(-1);
  1137.  
  1138.         if (i < 1024)                    /* not enough room to work with */
  1139.             return(ndone);
  1140. /*
  1141. *  process up to 512 source bytes for output (could produce 1K bytes out) 
  1142. */
  1143.         if (nsrc - ndone > 512)
  1144.             lim = 512;
  1145.         else
  1146.             lim = nsrc-ndone;
  1147.  
  1148.         p = (char *) buf + ndone;                /* where to start this block */
  1149.         q = mungbuf;                    /* where munged stuff goes */
  1150.         for (i=0; i < lim; i++) {
  1151.             if (*p == EOLCHAR) {
  1152.                 *q++ = 13;
  1153.                 *q++ = 10;
  1154.                 p++;
  1155.             }
  1156.             else
  1157.                 *q++ = *p++;
  1158.         }
  1159.         ndone += lim;                    /* # of chars processed */
  1160.         nout = q-mungbuf;                /* # of chars new */
  1161.  
  1162.         if ( nout != netwrite(pnum,mungbuf,nout) )
  1163.             putln("error in Sfwrite");    /* send them on their way */
  1164.  
  1165.     }
  1166.  
  1167.     return(ndone);
  1168. }
  1169.  
  1170. /*********************************************************************/
  1171. /*
  1172. *  FTP receive and send file functions
  1173. */
  1174. static int fcnt=0;
  1175.  
  1176. void ftpd
  1177.   (
  1178.     int code,
  1179.     int curcon
  1180.   )
  1181.     {
  1182.     int i,a;
  1183.     char tempp[256];
  1184.     char theDir[256];
  1185.  
  1186.     if (curcon != ftpdata)        /* wrong event, was for someone else */
  1187.         return;
  1188.  
  1189.     switch (ftpstate) {
  1190.         default:
  1191.             break;
  1192.  
  1193.         case 40:                /* list file names in current dir */
  1194.  
  1195.             if (code == CONFAIL)    /* something went wrong */
  1196.                 fcnt = -1;
  1197.             if (code != CONOPEN)     /* waiting for connection to open */
  1198.                 break;
  1199.             
  1200.             ftpstate = 41;
  1201.  
  1202. /*
  1203. *  send the "nextfile" string and then see if there is another file
  1204. *  name to send
  1205. */
  1206.         case 41:
  1207.             netputuev(SCLASS,FTPACT,ftpdata);
  1208.             netpush(ftpdata);
  1209.             i = strlen(nextfile);
  1210.             if (i != netwrite(ftpdata,nextfile,i)) {
  1211.                 CRESP(1);
  1212.                 fcnt = -1;
  1213.                 break;
  1214.             }
  1215.             netwrite(ftpdata,"\015\012",2);
  1216.             if (NULL == (nextfile = nextname())) {    /* normal end */
  1217.                 ftpstate = 22;               /* push data through */
  1218.             }
  1219.             break;
  1220.             
  1221.         case 30:
  1222.             if (code == CONFAIL)    /* something went wrong */
  1223.                 fcnt = -1;
  1224.             if (code != CONOPEN)    /* waiting for connection to open */
  1225.                 break;
  1226.             ftpstate = 31;
  1227.             crfound = 0;
  1228.             len = xp = 0;
  1229.             filelen = 0L;
  1230.             dopwd(theDir,256);                    /* get directory */
  1231.             sprintf(tempp,"remote --> %s/%s\015\012",theDir,newfile);
  1232.             ftpmess(tempp);
  1233.             netputevent(USERCLASS,FTPBEGIN,-2);
  1234.             
  1235.         case 31:
  1236. /*
  1237. * file has already been opened, take everything from the connection
  1238. * and place into the open file: ftpfh
  1239. */
  1240.             do {
  1241.             /* wait until xs is full before writing to disk */
  1242.                 if (len <= 2000) {
  1243.  
  1244.                     if (xp) {
  1245. #ifdef MACBINARY
  1246.                         if (0 > MBwrite(mbfp, xs, xp)) {
  1247.                             MBclose( mbfp);            /* Close on Disk Full Error */
  1248.                             ftpstate=22;
  1249.                             CRESP(27); 
  1250.                             ftpmess(messs);
  1251.                             if( (a = netclose(ftpdata)) !=0 ) putln("error closing net ");
  1252.                             fcnt = -1;
  1253.                             mbfp=NULL;
  1254.  
  1255.                             putln("there is a problem");
  1256.                             break;
  1257.                         }
  1258. #else
  1259.                         if (0 > write(ftpfh,xs,xp)) { /* disk full err */
  1260.                             putln("\015\012we have a disk full error in asc\015\012");
  1261.  
  1262.                             CRESP(27);
  1263.                             netclose(ftpdata);
  1264.                             fcnt = -1;
  1265.  
  1266.                             break;
  1267.                         }
  1268. #endif
  1269.                         xp = 0;
  1270.                     }
  1271.                     len = BUFFERS;        /* expected or desired len to go */
  1272.                 }
  1273.  
  1274.                 if (ftptmode == FAMODE)
  1275.                     fcnt = Sfread(ftpdata,&xs[xp],len);
  1276.                 else
  1277.                     fcnt = netread(ftpdata,&xs[xp],len);
  1278.  
  1279.                 if (fcnt >= 0) {
  1280.                     len -= fcnt;
  1281.                     xp += fcnt;
  1282.                     filelen += fcnt;
  1283.                 }
  1284.  
  1285.                 if (fcnt < 0) {
  1286. #ifdef MACBINARY
  1287.                     if (0 > MBwrite( mbfp, xs, xp)) {
  1288.                         CRESP(27);
  1289.                         MBclose( mbfp);            /* Close file on error */
  1290.                         break;
  1291.                     }
  1292.                     MBclose( mbfp );
  1293. #else
  1294.                     if (0 > write(ftpfh,xs,xp)) { /* disk full check */
  1295.                         CRESP(27);
  1296.                         break;
  1297.                     }
  1298.                     close(ftpfh);
  1299. #endif
  1300.                     ftpfh = 0;
  1301.                     CRESP(5);
  1302.                 }
  1303.  
  1304.             } while (fcnt > 0);
  1305.             break;
  1306.  
  1307.         case 20:
  1308.  
  1309.             if (code == CONFAIL)    /* something went wrong */
  1310.                 fcnt = -1;
  1311.             if (code != CONOPEN)    /* waiting for connection to open */
  1312.                 break;
  1313.             ftpstate = 21;
  1314. #ifdef MACBINARY
  1315.             filelen = MBsize( mbfp );
  1316. #else
  1317.             filelen = lseek(ftpfh,0L,2);        /* how long is file? */
  1318.             lseek(ftpfh,0L,0);                    /* back to beginning */
  1319. #endif
  1320.             towrite = 0;
  1321.             xp = 0;
  1322.             netputevent(USERCLASS,FTPBEGIN,-1);
  1323.  
  1324.         case 21:
  1325. /*
  1326. *  transfer file(s) to the other host via ftp request
  1327. *  file is already open = ftpfh
  1328. */
  1329.             netputuev(SCLASS,FTPACT,ftpdata);
  1330.         
  1331.             if (towrite <= xp) {
  1332.  
  1333.                 i = BUFFERS;
  1334. #ifdef MACBINARY
  1335.                 towrite = MBread( mbfp, xs, i);
  1336. #else
  1337.                 towrite = read(ftpfh,xs,i);
  1338. #endif
  1339.                 xp = 0;
  1340.             }
  1341.  
  1342.             if (towrite <= 0 || netest(ftpdata)) {        /* we are done */
  1343.                 ftpstate = 22;
  1344.                 break;
  1345.             }
  1346.  
  1347.             if (ftptmode == FAMODE)
  1348.                 i = Sfwrite(ftpdata,&xs[xp],towrite-xp);
  1349.             else
  1350.                 i = netwrite(ftpdata,&xs[xp],towrite-xp);
  1351.  
  1352.  
  1353. /*            printf(" %d %d %d \012",i,xp,towrite);
  1354.             n_row(); */
  1355.  
  1356.             if (i > 0) {
  1357.                 xp += i;
  1358.                 filelen -= i;
  1359.                 if (filelen < 0L)
  1360.                     filelen = 0L;
  1361.             }
  1362.  
  1363.             break;
  1364.  
  1365.         case 22:        /* wait for data to be accepted */
  1366.             netputuev(SCLASS,FTPACT,ftpdata);
  1367.  
  1368.             fcnt = netpush(ftpdata);        /* will go negative on err */
  1369.             if (!fcnt || netest(ftpdata))
  1370.                 fcnt = -1;
  1371.             if (fcnt < 0) {
  1372.                 CRESP(5);
  1373.             }
  1374.             break;
  1375.  
  1376.         case 0:
  1377.             break;
  1378.  
  1379.     }  /* end of switch */
  1380.  
  1381. /*
  1382. *  after reading from connection, if the connection is closed,
  1383. *  reset up shop.
  1384. */
  1385.     if (fcnt < 0) {
  1386. #ifdef MACBINARY
  1387.         if (mbfp) {
  1388.             MBclose( mbfp );
  1389.             mbfp = NULL;
  1390.  
  1391.  
  1392.  
  1393. /* */        
  1394.         }
  1395. #else
  1396.         if (ftpfh > 0) {
  1397.             close(ftpfh);
  1398.             ftpfh = 0;
  1399.         }
  1400. #endif
  1401.         ftpstate = 0;
  1402.         fcnt = 0;
  1403.         if (ftpdata >= 0) {
  1404.             netclose(ftpdata);
  1405.             netputevent(USERCLASS,FTPEND,-1);
  1406.             ftpdata = -1;
  1407.         }
  1408.     }
  1409.  
  1410. }
  1411.  
  1412. /***********************************************************************/
  1413. /* Sftpname and Sftpuser and Sftphost
  1414. *  record the name of the file being transferred, to use in the status
  1415. *  line updates
  1416. */
  1417.  
  1418. void Sftpname
  1419.   (
  1420.     char *s
  1421.   )
  1422.   {
  1423.     strcpy(s, newfile);
  1424.   }
  1425.  
  1426. void Sftpuser
  1427.   (
  1428.     char *user
  1429.   )
  1430.   {
  1431.     strcpy(user, myuser);            /* user name entered to log in */
  1432.   }
  1433.  
  1434. void Sftphost
  1435.   (
  1436.     char *host
  1437.   )
  1438.   {
  1439.     movebytes(host, hisuser, 4);        /* IP address of remote host */
  1440.   }
  1441.  
  1442. void Sftpstat
  1443.   (
  1444.     long *byt
  1445.   )
  1446.     {
  1447.     
  1448.     if (ftptmode != FAMODE && MacBinary)    /* MacBinary transfer */
  1449.         *byt = -1;
  1450.     else
  1451.         *byt = filelen;
  1452.  
  1453. }
  1454.  
  1455. #ifdef MACBINARY
  1456. void MBstat
  1457.   (
  1458.     char nlen,
  1459.     int godknows,
  1460.     int anotherlen
  1461.   )
  1462.   {
  1463. #pragma unused(nlen, godknows, anotherlen)
  1464.   }
  1465. #endif
  1466.